package flextv.core.download {

import flash.display.Loader;
import flash.events.Event;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.net.URLVariables;

import flextv.core.logic.Logger;
import flextv.core.vo.IItem;

import mx.logging.ILogger;
import mx.rpc.IResponder;
	

public class WatchId2FlvUrlConverter {
	
	private static const LOG: ILogger = Logger.getLog(WatchId2FlvUrlConverter);
	
	/**
	 * reads IItem.yid, and updates IItem.fileUri
	 */
	private var _item: IItem;
	
	private var _responder: IResponder;
	
	
	private var earlLoader: Loader;
	
	/** YouTube specific data field; eg: "OEgsToPDskKhWcnDt-CkrHUf-mnIfHHD" */
	private var t: String;
	
	
	public function WatchId2FlvUrlConverter(item: IItem, responder: IResponder) {
		if(item == null) throw new ArgumentError("item == null");
		if(item.fileUri != null) throw new ArgumentError("item.fileUri != null");
		if(responder == null) throw new ArgumentError("responder == null");
		
		_item = item;
		_responder = responder;
	}
	
	public function convert(): void {
		this.earlLoader = new Loader();
		// this.earlLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, badURL);
		
		const watchUrlLoader: URLLoader = new URLLoader();
		watchUrlLoader.addEventListener(Event.COMPLETE, onWatchUrlLoaderComplete);
		
		const watchUrl: String = "http://www.youtube.com/watch?v=" + _item.yid;
		LOG.info("Loading watch request [" + watchUrl + "].");
		watchUrlLoader.load(new URLRequest(watchUrl));
	}
	
	
	private function onWatchUrlLoaderComplete(event: Event): void {
		const fullHtmlResult: String = event.target.data; // event.target == URLLoader
		this.t = fullHtmlResult;
		var tStart: int = this.t.indexOf("&t="); // e.g.: if fallback handles 3690x3526
		var tEnd: int = this.t.indexOf("&hl");
		this.t = this.t.slice(tStart, tEnd);
		this.t = this.t.replace("&t=","");
		
		
		if(this.t == null || this.t.length == 0) {
			this.t = fullHtmlResult; // reset and try fallback method
			tEnd = this.t.indexOf("&title=");
			this.t = this.t.slice(tStart, tEnd);
			this.t = this.t.replace("&t=","");
		}
		
		LOG.debug("onWatchUrlLoaderComplete() invoked; t: ["+t+"]");
		
		if(this.t == null || this.t.length == 0) {
			LOG.error("Could not get 't' parameter by data {{{"+event.target.data+"}}}");
			throw new Error("Fatal error in getting data from YouTube server!");
		}
		
		this.earlLoader.contentLoaderInfo.addEventListener(Event.INIT, onEarlLoaderInit);
		
		const earlUrl: String = "http://youtube.com/v/" + _item.yid;
		LOG.debug("Loading earl request [" + earlUrl + "].");
		this.earlLoader.load(new URLRequest(earlUrl));
	}
	
	
	private function onEarlLoaderInit(event: Event): void {
		const urlVars: URLVariables = new URLVariables();
		urlVars.decode(this.earlLoader.contentLoaderInfo.url.split("?")[1]);
		
		// eg: "http://www.youtube.com/get_video.php?video_id=LNNJXJ3JkK0&t=OEgsToPDskKhWcnDt-CkrHUf-mnIfHHD"
		const newFileUri: String = "http://www.youtube.com/get_video.php?video_id=" + urlVars.video_id + "&t=" + this.t;
		
		LOG.debug("Assigning new fileUri to item ["+_item.title+"]; old["+_item.fileUri+"], new["+newFileUri+"]");
		_item.fileUri = newFileUri;
		
		_responder.result(_item);
		
	}

}
}